//********************************************************************************************************************//
//ORGANIZATION:
//AUTHOR: bpeng(bogers.peng@gmail.com)
//SUMMARY:
//********************************************************************************************************************//
#include "../VariableGather.h"
#include "System/Base/IteratorBuilder.h"

using namespace Native::Compiling;
using namespace Native::Compiling::Sql;

CVariableGather::CVariableGather()
{
}

CVariableGather::CVariableGather(C_VARIABLE_GATHER& that) :
    CGather(that),
    _obsevers(that._obsevers)
{
}

CVariableGather::CVariableGather(C_VARIABLE_GATHER&& that) :
    CGather(that),
    _obsevers(that._obsevers)
{
}

CVariableGather::~CVariableGather()
{
}

void CVariableGather::Update() const throw()
{
    try {
        auto variable = Cast();
        auto iterator = UArrayIteratorBuilder<IObserve<CVariable>*>::CreateForward(&_obsevers);

        NATIVE_FOREACH(&iterator, each) {
            (*each)->Send(dynamic_cast<const ICast<CVariable>*>(this));
        }
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"Update", e);
    }
}

CVariable CVariableGather::Cast() const throw()
{
    try {
        CVariable variable;

        variable.Starting(_field.Starting());
        variable.Ending(_field.Ending());
        variable.Sequence(_field.Sequence());
        variable.Name(_properies.Value(VARABLE_GATHER_NAME_KEY));
        variable.Type(_properies.Value(VARABLE_GATHER_TYPE_KEY));
        variable.Value(_properies.Value(VARABLE_GATHER_VALUE_KEY));
        variable.Output(CBool(_properies.Value(VARABLE_GATHER_OUTPUT_KEY).ToString()).Value());

        return move(variable);
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"Cast", e);
    }
}

void CVariableGather::Register(IObserve<CVariable>* obsever) throw()
{
    CNullPointerException::Check(NATIVE_SCENE(L"Register"), (POINTER)obsever, L"obsever");

    _obsevers.Append(obsever);
}

void CVariableGather::CollectName(C_STRING& name) throw()
{
    try {
        Collect(VARABLE_GATHER_NAME_KEY, name);
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"CollectName", e);
    }
}

void CVariableGather::CollectType(C_STRING& type) throw()
{
    try {
        Collect(VARABLE_GATHER_TYPE_KEY, type);
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"CollectType", e);
    }
}

void CVariableGather::CollectValue(C_STRING& value) throw()
{
    try {
        Collect(VARABLE_GATHER_VALUE_KEY, value);
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"CollectValue", e);
    }
}

void CVariableGather::CollectOutput(bool output) throw()
{
    try {
        Collect(VARABLE_GATHER_OUTPUT_KEY, CBool(output).ToString());
    } catch(CException& e) {
        NATIVE_THROW_CAUGHT(L"CollectOutput", e);
    }
}

C_VARIABLE_GATHER& CVariableGather::operator=(C_VARIABLE_GATHER& rvalue)
{
    CGather::operator=(rvalue);
    
    _obsevers = rvalue._obsevers;

    return *this;
}
